home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2001 Spring / Oh!X 2001 Spring Special CD-ROM (Japan).7z / Oh!X 2001 Spring Special CD-ROM (Japan) (Track 1).bin / JAVA / spman040 / ShootSaucer.java < prev    next >
Text File  |  1996-06-06  |  10KB  |  341 lines

  1. import java.applet.Applet;
  2. import java.applet.AudioClip;
  3. import java.lang.Math;
  4. import java.util.Random;
  5. import java.util.Date;
  6. import java.awt.*;
  7.  
  8. public class ShootSaucer extends Applet implements Runnable {
  9.     static final int ENEMY = 6;    // 敵は最大6機
  10.     static final int WIDTH = 320, HEIGHT = 240;    // 背景サイズ
  11.     SpriteCanvas sc;    // スプライトキャンバス
  12.     int mx, my, mbx, mby;    // 自分の座標とミサイルの座標
  13.     int ex[] = new int[ENEMY], ey[] = new int[ENEMY];    // 敵の座標
  14.     int ebx[] = new int[ENEMY], eby[] = new int[ENEMY];    // 敵の弾の座標
  15.     int count[] = new int[ENEMY], direct[] = new int[ENEMY];    // 敵の回転
  16.     int edx[] = new int[ENEMY], edy[] = new int[ENEMY];    // 敵の弾の速度
  17.     int score;    // スコア
  18.     boolean mbf, ef[] = new boolean[ENEMY], ebf[] = new boolean[ENEMY];
  19.     // 自分のミサイル、敵、敵の弾の表示フラグ
  20.     boolean up, down, left, right, space;    // キー入力フラグ
  21.     Thread thread=null;
  22.     MediaTracker mt;
  23.     Random aRandom = new Random();
  24.     Math aMath;
  25.     Label Score;
  26.     boolean play = false;    // ゲーム中フラグ
  27.     AudioClip gun, bomb, wow, hit[] = new AudioClip[4];
  28.     public void init(){
  29.         Image image;
  30.         int i;
  31.         // 効果音読み込み
  32.         gun = getAudioClip( getDocumentBase(), "audio/gun.au" );
  33.         bomb = getAudioClip( getDocumentBase(), "audio/bomb.au" );
  34.         wow = getAudioClip( getDocumentBase(), "audio/wow.au" );
  35.         hit[0] = getAudioClip( getDocumentBase(), "audio/comeon.au" );
  36.         hit[1] = getAudioClip( getDocumentBase(), "audio/get.au" );
  37.         hit[2] = getAudioClip( getDocumentBase(), "audio/iyao.au" );
  38.         hit[3] = getAudioClip( getDocumentBase(), "audio/wao.au" );
  39.         // スプライトキャンバス作成
  40.         // パターンは、自機、ミサイル、敵6パターン、敵の弾、爆発
  41.         // プレーンは、自機、ミサイル、敵6機、敵の弾6発
  42.         sc = new SpriteCanvas( 1+1+6+1+1, 1+1+ENEMY+ENEMY, WIDTH, HEIGHT, this );
  43.         setLayout( new BorderLayout() );
  44.         score = 0;
  45.         Score = new Label( "SCORE "+score, Label.CENTER );
  46.         add( "Center", sc );
  47.         add( "North", Score );
  48.         add( "South", new Button( "Start" ) );
  49.         mt = new MediaTracker( this );
  50.         image = getImage( getDocumentBase(), "image/earth.gif" );    // 背景
  51.         mt.addImage( image, 0 );
  52.         sc.WaitLoadImage( mt, 0 );    // 読み込むまでスプライトを表示しない
  53.         sc.SetBGImage( image );        // 背景に設定
  54.         image = getImage( getDocumentBase(), "image/Fighter.gif" );    // 自機
  55.         mt.addImage( image, 0 );
  56.         sc.Define( 0, image );        // パターン0に設定
  57.         image = getImage( getDocumentBase(), "image/Missile.gif" );    // ミサイル
  58.         mt.addImage( image, 0 );
  59.         sc.Define( 1, image );        // パターン1に設定
  60.         for( i=1; i<=6; i++ ){
  61.             // 敵の回転6パターン
  62.             image = getImage( getDocumentBase(), "image/Enemy"+i+".gif" );
  63.             mt.addImage( image, 0 );
  64.             sc.Define( i+1, image );    // パターン2~7に設定
  65.         }
  66.         image = getImage( getDocumentBase(), "image/Bomb.gif" );    // 敵の弾
  67.         mt.addImage( image, 0 );
  68.         sc.Define( 8, image );        // パターン8に設定
  69.         image = getImage( getDocumentBase(), "image/Crush.gif" );    // 爆発
  70.         mt.addImage( image, 0 );
  71.         sc.Define( 9, image );        // パターン9に設定
  72.         for( i=0; i<ENEMY; i++ ) ef[i] = ebf[i] = false;
  73. //        速いインタプリタなら、下のコメントを取った方がいいかも
  74. //        sc.SetClipMode( true );
  75.     }
  76.     public void start(){
  77.         if( thread==null ){
  78.             thread = new Thread( this );
  79.             thread.start();
  80.         }
  81.     }
  82.     public void stop(){
  83.         if( thread!=null ){
  84.             thread.stop();
  85.             thread = null;
  86.         }
  87.     }
  88.     public void run(){
  89.         try {
  90.             mt.waitForID( 0 );
  91.         } catch( InterruptedException e ){
  92.             return;
  93.         }
  94.         while( true ){
  95.             try {
  96.                 Thread.sleep( 50 );
  97.             } catch( InterruptedException e ){
  98.                 break;
  99.             }
  100.             for( int i=0; i<ENEMY; i++ ){    // 敵の動き
  101.                 int r = aMath.abs(aRandom.nextInt());
  102.                 if( ef[i]==false ){    // 敵は出ていない
  103.                     sc.Hide( i+ENEMY+2, i+ENEMY+2 );
  104.                     if( (r&0x7f)<=score>>3 ) InitEnemy( i );    // 出現
  105.                 } else {
  106.                     switch( direct[i] ){    // 回転の向き
  107.                     case 1:// 左向き
  108.                         count[i]++;
  109.                         if( count[i]>=6 ) count[i] = 0;
  110.                         sc.Set( i+ENEMY+2, count[i]+2 );    // 回転
  111.                         ex[i] -= 2;
  112.                         break;
  113.                     case 2:// 右向き
  114.                         count[i]--;
  115.                         if( count[i]<0 )count[i] = 5;
  116.                         sc.Set( i+ENEMY+2, count[i]+2 );    // 回転
  117.                         ex[i] += 2;
  118.                         break;
  119.                     default:// 回転してない
  120.                         switch( r&0x3f ){
  121.                         case 1:    // 左向き回転させる
  122.                                 direct[i] = 1;
  123.                                 count[i] = 1;
  124.                                 // 弾発射
  125.                                 if( ((r>>8)&0xff)<score ) Bomb( i );
  126.                                 break;
  127.                         case 2:    // 右向き回転させる
  128.                                 direct[i] = 2;
  129.                                 count[i] = 5;
  130.                                 // 弾発射
  131.                                 if( ((r>>8)&0xff)<score ) Bomb( i );
  132.                                 break;
  133.                         }
  134.                     }
  135.                 }
  136.                 if( ef[i] ){
  137.                     ey[i] += 4;
  138.                     if( ey[i]>240 ){    // 画面から出ていった
  139.                         ef[i] = false;
  140.                         sc.Hide( i+ENEMY+2, i+ENEMY+2 );    // スプライト非表示
  141.                     } else sc.Move( i+ENEMY+2, ex[i], ey[i] );    // 移動
  142.                 }
  143.                 if( ebf[i] ){
  144.                     ebx[i] += edx[i];
  145.                     eby[i] += edy[i];
  146.                     if( ebx[i]<-32 || ebx[i]>WIDTH ||
  147.                         eby[i]<-32 || eby[i]>HEIGHT ){    // 弾が出ていった
  148.                         sc.Hide( i+2, i+2 );    // スプライト非表示
  149.                         ebf[i] = false;
  150.                     } else {
  151.                         sc.Move( i+2, ebx[i], eby[i] );    // 移動
  152.                     }
  153.                 }
  154.             }
  155.             if( play ){    // ゲーム中
  156.                 // キー判定
  157.                 if( up && !down ) if( my>4 ) my -= 4;
  158.                 if( down && !up ) if( my<HEIGHT-32-4 ) my += 4;
  159.                 if( left && !right ) if( mx>4 ) mx -= 4;
  160.                 if( right && !left ) if( mx<WIDTH-32-4 ) mx += 4;
  161.                 sc.Move( 0, mx, my );    // 移動
  162.                 // ミサイルが出ていないときにスペースキーを押した
  163.                 if( space && !mbf ){
  164.                     mbx = mx;
  165.                     mby = my;
  166.                     mbf = true;
  167.                     sc.Set( 1, 1 );        // ミサイルプレーンをセット
  168.                     sc.Show( 1, 1 );    // ミサイルプレーンを表示
  169.                     gun.play();            // SE
  170.                 }
  171.                 if( mbf ){    // ミサイルが出ている
  172.                     mby -= 16;
  173.                     if( mby<-32 ){
  174.                         sc.Hide( 1, 1 );    // 画面から出ていった
  175.                         mbf = false;
  176.                     } else {
  177.                         if( HitCheck() ){    // 敵との当たり判定
  178.                             mbf = false;
  179.                             sc.Hide( 1, 1 );    // ヒットしたらミサイルも消す
  180.                         } else sc.Move( 1, mbx, mby );    // 移動
  181.                     }
  182.                 }
  183.                 if( CrushCheck() ){    // 自機の敵および敵の弾との当たり判定
  184.                     sc.Set( 0, 9 );    // 死んじゃった
  185.                     sc.Hide( 1, 1 );
  186.                     play = false;
  187.                 }
  188.             }
  189.             sc.Draw();    // スプライト描画
  190.         }
  191.     }
  192.     void InitEnemy( int n ){    // 敵の初期化
  193.         ex[n] = aMath.abs(aRandom.nextInt())%(WIDTH-32);
  194.         ey[n] = -32;
  195.         ef[n] = true;
  196.         direct[n] = 0;
  197.         sc.Set( n+ENEMY+2, 2 );    // プレーンセット
  198.         sc.Show( n+ENEMY+2, n+ENEMY+2 );    // 表示
  199.     }
  200.     boolean HitCheck()    // ミサイルと敵の当たり判定
  201.     {
  202.         boolean result = false;
  203.         for( int i=0; i<ENEMY; i++ ){
  204.             if( ef[i] ){    // 敵は出ている?
  205.                 if( ex[i]>mbx-16 && ex[i]<mbx+16 &&
  206.                     ey[i]>mby-20 && ey[i]<mby+20 ){    // 当たり
  207.                     ef[i] = false;
  208.                     sc.Set( i+ENEMY+2, 9 );    // 敵プレーンに爆発パターンをセット
  209.                     score += 1;
  210.                     Score.setText( "SCORE "+score );
  211.                     result = true;
  212.                     int r = aMath.abs(aRandom.nextInt());
  213.                     hit[r%4].play();    // SE
  214.                     if( (r&0xf)<score>>3 ) Bomb( i );    // 打ち返してきた
  215.                     break;
  216.                 }
  217.             }
  218.         }
  219.         return result;
  220.     }
  221.     boolean CrushCheck()    // 自機の当たり判定
  222.     {
  223.         boolean result = false;
  224.         for( int i=0; i<ENEMY; i++ ){    // 敵との判定
  225.             if( ef[i] ){    // 敵は出ている?
  226.                 if( ex[i]>mx-20 && ex[i]<mx+20 &&
  227.                     ey[i]>my-20 && ey[i]<my+20 ){    // 当たり
  228.                     ef[i] = false;
  229.                     sc.Set( i+ENEMY+2, 9 );    // 敵プレーンに爆発パターンをセット
  230.                     score += 1;
  231.                     Score.setText( "SCORE "+score );
  232.                     result = true;
  233.                     bomb.play();    // ドカーン
  234.                     break;
  235.                 }
  236.             }
  237.             if( ebf[i] ){    // 敵の弾は出ている?
  238.                 if( ebx[i]>mx-16 && ebx[i]<mx+16 &&
  239.                     eby[i]>my-16 && eby[i]<my+16 ){    // 当たり
  240.                     ebf[i] = false;
  241.                     sc.Hide( i+2, i+2 );    // 弾を消す
  242.                     result = true;
  243.                     bomb.play();    // ドカーン
  244.                     break;
  245.                 }
  246.             }
  247.         }
  248.         return result;
  249.     }
  250.     void Bomb( int i )    // 敵の弾発射
  251.     {
  252.         // 敵の弾が発射済みかゲーム中でなければ発射しない
  253.         if( ebf[i] || !play ) return;
  254.         ebx[i] = ex[i];
  255.         eby[i] = ey[i];
  256.         int dx, dy, ux, uy;
  257.         // 適当に弾の向き設定
  258.         dx = mx-ebx[i];
  259.         dy = my-eby[i];
  260.         ux = dx>=0?dx:-dx;
  261.         uy = dy>=0?dy:-dy;
  262.         if( ux>uy ){
  263.             edx[i] = 5;
  264.             edy[i] = 3;
  265.         } else {
  266.             edx[i] = 3;
  267.             edy[i] = 5;
  268.         }
  269.         if( dx<0 ) edx[i] = -edx[i];
  270.         if( dy<0 ) edy[i] = -edy[i];
  271.         ebf[i] = true;
  272.         sc.Set( i+2, 8 );    // 弾プレーンセット
  273.         sc.Show( i+2, i+2 );    // 表示
  274.         wow.play();    // SE
  275.     }
  276.     public boolean keyDown( Event e, int key ){
  277.         switch( key ){
  278.         case 1004://↑
  279.             up = true;
  280.             break;
  281.         case 1005://↓
  282.             down = true;
  283.             break;
  284.         case 1006:// ←
  285.             left = true;
  286.             break;
  287.         case 1007:// →
  288.             right = true;
  289.             break;
  290.         case ' ':
  291.             space = true;
  292.             break;
  293.         }
  294.         return true;
  295.     }
  296.     public boolean keyUp( Event e, int key ){
  297.         switch( key ){
  298.         case 1004://↑
  299.             up = false;
  300.             break;
  301.         case 1005://↓
  302.             down = false;
  303.             break;
  304.         case 1006:// ←
  305.             left = false;
  306.             break;
  307.         case 1007:// →
  308.             right = false;
  309.             break;
  310.         case ' ':
  311.             space = false;
  312.             break;
  313.         }
  314.         return true;
  315.     }
  316.     public boolean action( Event e, Object o ){
  317.         if( e.target instanceof Button ){
  318.             if( play==false ){    // ゲームスタート
  319.                 play = true;
  320.                 score = 0;
  321.                 Score.setText( "SCORE "+score );
  322.                 for( int i=0; i<ENEMY; i++ ){    // 敵の初期化
  323.                     ef[i] = false;
  324.                     ebf[i] = false;
  325.                 }
  326.                 sc.Hide();    // 取りあえず全部隠しといて
  327.                 mx = (WIDTH-32)/2;
  328.                 my = HEIGHT-32-32;
  329.                 sc.Set( 0, 0 );    // 自機プレーンセット
  330.                 sc.Set( 1, 1 );    // ミサイルプレーンセット
  331.                 sc.Move( 0, mx, my );    // 自機の座標設定
  332.                 sc.Show( 0, 0 );    // 自機表示
  333.                 up = down = left = right = space = false;
  334.                 mbf = false;
  335.             }
  336.             return true;
  337.         }
  338.         return false;
  339.     }
  340. }
  341.